package com.gl.order.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.gl.order.entity.TRole;
import com.gl.order.entity.TRoleMenu;
import com.gl.order.entity.TRolePermission;
import com.gl.order.entity.dto.RoleDto;
import com.gl.order.entity.dto.RolePageDto;
import com.gl.order.entity.dto.UpdateRoleDto;
import com.gl.order.entity.vo.RoleVo;
import com.gl.order.mapper.TRoleMapper;
import com.gl.order.mapper.TRoleMenuMapper;
import com.gl.order.mapper.TRolePermissionMapper;
import com.gl.order.service.RoleService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

@Service
@Transactional(rollbackFor = Exception.class)
public class RoleServiceImpl extends ServiceImpl<TRoleMapper,TRole> implements RoleService {


    @Autowired
    TRolePermissionMapper rolePermissionMapper;
    @Autowired
    TRoleMenuMapper tRoleMenuMapper;

    @Override
    public void add(RoleDto dto) {
        TRole role = new TRole();
        role.setName(dto.getName());
        role.setRemark(dto.getRemark());
        role.setRoleCode(dto.getRoleCode());
        save(role);
        if(CollUtil.isNotEmpty(dto.getPermissions())){
//            addRolePermission(role.getId(),dto.getPermissions());
            addRoleMenu(role.getId(),dto.getPermissions());
        }
    }

    @Override
    public void addRolePermission(String roleId, List<String> permissionsIds) {
        delRolePermissionRef(roleId);
        permissionsIds.stream().forEach(permissionsId -> {
            rolePermissionMapper.insert(new TRolePermission(roleId,permissionsId));
        });
    }

    @Override
    public void addRoleMenu(String roleId, List<String> menuIds) {
        delRoleMenu(roleId);
        menuIds.stream().forEach(menuId -> {
            tRoleMenuMapper.insert(new TRoleMenu(roleId,menuId));
        });
    }

    @Override
    public void delRole(String id) {
        // 删除权限和角色的关联
        delRolePermissionRef(id);
        delRoleMenu(id);
        // 删除角色
        removeById(id);
    }

    @Override
    public void delRoles(List<String> ids) {
        if(!CollectionUtils.isEmpty(ids)){
            ids.stream().forEach(id -> {
                delRole(id);
            });
        }
    }

    @Override
    public List<TRole> list() {
        LambdaQueryWrapper<TRole> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.orderByDesc(TRole::getCreateTime);
        return list(queryWrapper);
    }

    @Override
    public TRole findById(String id) {
        return getById(id);
    }

    @Override
    public TRole findByNmaeOrCode(String name, String code) {
        QueryWrapper<TRole> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(TRole::getName,name).or().eq(TRole::getRoleCode,code);
        TRole role = getOne(queryWrapper);
        return role;
    }

    @Override
    public void updateRole(UpdateRoleDto dto) {
        TRole check_role = getById(dto.getId());
        if(Objects.isNull(check_role)){
            throw new NullPointerException("角色不存在");
        }
        TRole role = new TRole();
        BeanUtils.copyProperties(dto,role);
        updateById(role);
        if(CollUtil.isNotEmpty(dto.getPermissions())){
            addRoleMenu(role.getId(),dto.getPermissions());
        }
    }

    @Override
    public IPage<RoleVo> pageOfRole(RolePageDto dto) {
        List<TRoleMenu> menus = tRoleMenuMapper.selectList(null);
        Page<RoleVo> page = new Page<>(dto.getPageNo(),dto.getPageSize());
        IPage<RoleVo> results =  baseMapper.pageOfRole(page, dto);
        if(!CollectionUtils.isEmpty(results.getRecords())){
            results.getRecords().stream().forEach(result ->{
               List<String> menuIds = menus.stream().filter(menu ->  Objects.equals(menu.getRoleId(),result.getId())).map(TRoleMenu::getMenuId).collect(Collectors.toList());
                result.setMenuIds(menuIds);
            });
        }
        return results;
    }

    public void  delRolePermissionRef(String roldeId){
        QueryWrapper<TRolePermission> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(TRolePermission::getRoleId,roldeId);
        rolePermissionMapper.delete(queryWrapper);
    }

    /**
     * 删除角色菜单关系
     * @param roldeId
     */
    public void  delRoleMenu(String roldeId){
        QueryWrapper<TRoleMenu> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(TRoleMenu::getRoleId,roldeId);
        tRoleMenuMapper.delete(queryWrapper);
    }
}
